package com.campus.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.common.config.CodeConfig;
import com.campus.entity.*;
import com.campus.entity.Clazz.Clazz;
import com.campus.entity.Clazz.ClazzStudent;
import com.campus.entity.System.SysUser;
import com.campus.entity.vo.Clazz.ClazzVO;
import com.campus.entity.vo.Student.StudentVO;
import com.campus.service.ClazzService;
import com.campus.service.ClazzStudentService;
import com.campus.service.StudentService;
import com.campus.service.SysUserService;
import com.campus.util.CopyPropertiesUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生表 前端控制器
 * </p>
 *
 * @author Alaskaboo
 * @since 2022-10-07
 */
@RestController
@RequestMapping("/api/student")
public class StudentController {
    @Autowired
    private StudentService studentService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private ClazzStudentService clazzStudentService;
    @Autowired
    private ClazzService clazzService;

    /**
     * 添加或者修改
     *
     * @param student
     * @return
     */
    @PostMapping
    @CacheEvict(value = "studentInfo", allEntries =true)
    public ResultBody save(@RequestBody Student student) {
        if (student.getId() == null || student.getId() == -1) {
            studentService.save(student);
        } else {
            studentService.updateById(student);
        }
        return ResultBody.ok().message(CodeConfig.SUCCESS.message);
    }

    /**
     * 根据学生Account查询
     *
     * @param account
     * @return
     */
    @RequestMapping("/info/{account}")
    @Cacheable(value = "studentInfo", key = "#account")
    public ResultBody selectByAccount(@PathVariable String account) {
        Student studentInfo = studentService.lambdaQuery().in(Student::getAccount, account).one();
        if (studentInfo == null) {
            return ResultBody.error(CodeConfig.QUERY_FAIL);
        }
        StudentVO studentVO = new StudentVO();
        BeanUtil.copyProperties(studentInfo, studentVO);
        List<Clazz> clazzInfo = clazzService.list(new QueryWrapper<Clazz>().inSql("id", "select class_id from t_clazz_student where student_id=" + studentInfo.getId()));
        List<ClazzVO> collect = clazzInfo.stream().map(clazz -> CopyPropertiesUtils.copyProperties(clazz, ClazzVO.class)).collect(Collectors.toList());
        studentVO.setClazzList(collect);
        return ResultBody.ok().data("studentInfo", studentVO).message(CodeConfig.QUERY_SUCCESS.message);
    }

    /**
     * 根据用户ID查询
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @Cacheable(value = "studentInfo", key = "#id")
    public ResultBody selectPermsById(@PathVariable Long id) {
        Student studentInfo = studentService.getById(id);
        StudentVO studentVO = new StudentVO();
        BeanUtil.copyProperties(studentInfo, studentVO);
        QueryWrapper(studentVO, studentInfo.getId());
        return ResultBody.ok().data("studentInfo", studentVO);
    }

    /**
     * 查询所有学生
     *
     * @param currentPage
     * @param pageSize
     * @param student
     * @return
     */
    @GetMapping("/{currentPage}/{pageSize}")
    @Cacheable(value = "studentInfo", key = "#student")
    public ResultBody selectStudentList(@PathVariable int currentPage, @PathVariable int pageSize, Student student) {
        Page<Student> studentPage = new Page<>(currentPage, pageSize);
        //分页
        IPage<StudentVO> studentInfo = studentService.selectStudentList(studentPage, student);
        List<StudentVO> records = studentInfo.getRecords();
        for (StudentVO student1 : records) {
            QueryWrapper(student1, student1.getId());
        }

        //如果当前页码值大于了总页码值，那么重新执行查询操作，使用最大页码值作为当前页码值
        if (studentInfo.getTotal() > 0) {
            return ResultBody.ok().data("studentInfo", studentInfo).message(CodeConfig.QUERY_SUCCESS.message);
        }
        return ResultBody.error().message(CodeConfig.QUERY_FAIL.message);
    }

    private void QueryWrapper(StudentVO student1, Long id) {
        List<Clazz> clazzList = clazzService.list(new QueryWrapper<Clazz>().inSql("id", "select class_id from t_clazz_student where student_id=" + id));
        List<ClazzVO> collect = clazzList.stream().map(clazz -> CopyPropertiesUtils.copyProperties(clazz, ClazzVO.class)).collect(Collectors.toList());
        student1.setClazzList(collect);
    }

    /**
     * 通过ids删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    @CacheEvict(value = "studentInfo", allEntries =true)
    public ResultBody deleteStudentByIds(Long[] ids) {
        try {
            studentService.removeByIds(Arrays.asList(ids));
            clazzStudentService.remove(new QueryWrapper<ClazzStudent>().in("student_id", ids));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBody.error();
        }
        return ResultBody.ok().message(CodeConfig.DELETE_USER.message);
    }

    /**
     * 更新学生班级信息
     *
     * @param id
     * @param clazzIds
     * @return
     */

    @PostMapping("/updateStudentClazzIds/{id}")
    @CacheEvict(value = "studentInfo", allEntries =true)
    public ResultBody updateStudents(@PathVariable(value = "id") Long id, @RequestBody Long[] clazzIds) {
        List<ClazzStudent> clazzStudentList = new ArrayList<>();
        Arrays.stream(clazzIds).forEach(clazzId -> {
            ClazzStudent clazzStudent = new ClazzStudent();
            clazzStudent.setClassId(clazzId);
            clazzStudent.setStudentId(id);
            clazzStudentList.add(clazzStudent);
        });
        clazzStudentService.remove(new QueryWrapper<ClazzStudent>().eq("student_id", id));
        clazzStudentService.saveBatch(clazzStudentList);
        return ResultBody.ok().data("clazzStudentList", clazzStudentList);
    }

    @PostMapping("/join/{id}")
    @CacheEvict(value = "studentInfo", allEntries =true)
    public ResultBody joinClazzStudent(@PathVariable(value = "id") Long id, String school, Integer classNum) {
        // 1. 通过school和classNum确定唯一数据
        Clazz clazz = clazzService.lambdaQuery().eq(Clazz::getSchool, school).eq(Clazz::getClassNum, classNum).one();
        //数据库无数据
        if (clazz == null) {
            return ResultBody.error().message(CodeConfig.Clazz_NOTFOUND.message);
        }
        // 2.比较用户输入和Clazz数据库表
        Long count = clazzStudentService.lambdaQuery().eq(ClazzStudent::getStudentId, id).eq(ClazzStudent::getClassId, clazz.getId()).count();
        if (count > 0) {
            return ResultBody.error().message(CodeConfig.JOIN_FAIL.message);
        }
        //校验成功写入数据库
        ClazzStudent clazzStudent = new ClazzStudent();
        clazzStudent.setStudentId(id);
        clazzStudent.setClassId(Long.valueOf(clazz.getId()));
        clazzStudentService.save(clazzStudent);
        return ResultBody.ok().data("clazzStudent", clazzStudent);
    }

    /**
     * 更新班委状态
     *
     * @param id
     * @param userType
     * @return
     */
    @PutMapping("/updateUserType/{id}/userType/{userType}")
    @CacheEvict(value = "studentInfo", allEntries =true)
    public ResultBody updateUserType(@PathVariable(value = "id") Integer id, @PathVariable(value = "userType") String userType) {
        Student student = studentService.lambdaQuery().eq(Student::getId, id).one();
        String account = student.getAccount();
        SysUser user = sysUserService.getByAccount(account);
        user.setUserType(userType);
        sysUserService.saveOrUpdate(user);
        return ResultBody.ok().message(CodeConfig.SUCCESS.message);
    }

}
